package com.project.source;

import java.math.BigInteger;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedHashMap;

public class IbanValidator {

	private static LinkedHashMap<String, Integer> countryCharLength;
	private static Hashtable<Character, Integer> charNumbers;

	static {
		countryCharLength = new LinkedHashMap<String, Integer>();
		countryCharLength.put("AL", 28); // Albania
		countryCharLength.put("AD", 24); // Andorra
		countryCharLength.put("AT", 20); // Austria
		countryCharLength.put("AZ", 28); // Azerbaijan

		countryCharLength.put("BE", 16); // Belgium
		countryCharLength.put("BH", 22); // Bahrain
		countryCharLength.put("BA", 20); // Bosnia and Herzegovina
		countryCharLength.put("BG", 22); // Bulgaria

		countryCharLength.put("CR", 21); // Costa Rica
		countryCharLength.put("HR", 21); // Croatia
		countryCharLength.put("CY", 28); // Cyprus
		countryCharLength.put("CZ", 24); // Czech Republic

		countryCharLength.put("DK", 18); // Denmark
		countryCharLength.put("DO", 28); // Dominican Republic

		countryCharLength.put("EE", 20); // Estonia

		countryCharLength.put("FO", 18); // Faroe Islands
		countryCharLength.put("FI", 18); // Finland
		countryCharLength.put("FR", 27); // France

		countryCharLength.put("GE", 22); // Georgia
		countryCharLength.put("DE", 22); // Germany
		countryCharLength.put("GI", 23); // Gibraltar
		countryCharLength.put("GR", 27); // Greece
		countryCharLength.put("GL", 18); // Greenland

		countryCharLength.put("HU", 27); // Hungary

		countryCharLength.put("IS", 26); // Iceland
		countryCharLength.put("IE", 22); // Ireland
		countryCharLength.put("IL", 23); // Israel
		countryCharLength.put("IT", 27); // Italy

		countryCharLength.put("KZ", 20); // Kazakhstan
		countryCharLength.put("KW", 30); // Kuwait

		countryCharLength.put("LV", 21); // Latvia
		countryCharLength.put("LB", 28); // Lebanon
		countryCharLength.put("LI", 21); // Liechtenstein
		countryCharLength.put("LT", 20); // Lithuania
		countryCharLength.put("LU", 20); // Luxembourg

		countryCharLength.put("MK", 19); // Macedonia
		countryCharLength.put("MT", 31); // Malta
		countryCharLength.put("MR", 27); // Mauritania
		countryCharLength.put("MU", 30); // Mauritius
		countryCharLength.put("MC", 27); // Monaco
		countryCharLength.put("MD", 24); // Moldova
		countryCharLength.put("ME", 22); // Montenegro

		countryCharLength.put("NL", 18); // Netherlands
		countryCharLength.put("NO", 15); // Norway

		countryCharLength.put("PK", 24); // Pakistan
		countryCharLength.put("PL", 28); // Poland
		countryCharLength.put("PT", 25); // Portugal

		countryCharLength.put("RO", 24); // Romania

		countryCharLength.put("SM", 27); // San Marino
		countryCharLength.put("SA", 24); // Saudi Arabia
		countryCharLength.put("RS", 22); // Serbia
		countryCharLength.put("SK", 24); // Slovakia
		countryCharLength.put("SI", 19); // Slovenia
		countryCharLength.put("ES", 24); // Spain
		countryCharLength.put("SE", 24); // Sweden
		countryCharLength.put("CH", 21); // Switzerland

		countryCharLength.put("TN", 24); // Tunisia
		countryCharLength.put("TR", 26); // Turkey

		countryCharLength.put("AE", 23); // United Arab Emirates
		countryCharLength.put("GB", 22); // United Kingdom

		countryCharLength.put("VG", 24); // Virgin Islands, British

		charNumbers = new Hashtable<Character, Integer>();
		charNumbers.put('A', 10);
		charNumbers.put('B', 11);
		charNumbers.put('C', 12);
		charNumbers.put('D', 13);
		charNumbers.put('E', 14);
		charNumbers.put('F', 15);
		charNumbers.put('G', 16);
		charNumbers.put('H', 17);
		charNumbers.put('I', 18);
		charNumbers.put('J', 19);
		charNumbers.put('K', 20);
		charNumbers.put('L', 21);
		charNumbers.put('M', 22);
		charNumbers.put('N', 23);
		charNumbers.put('O', 24);
		charNumbers.put('P', 25);
		charNumbers.put('Q', 26);
		charNumbers.put('R', 27);
		charNumbers.put('S', 28);
		charNumbers.put('T', 29);
		charNumbers.put('U', 30);
		charNumbers.put('V', 31);
		charNumbers.put('W', 32);
		charNumbers.put('X', 33);
		charNumbers.put('Y', 34);
		charNumbers.put('Z', 35);
	}

	public static Boolean Check(String Iban) {
		Iban = Iban.toUpperCase();
		String countryCode = Iban.substring(0, 2);

		if (!countryCharLength.containsKey(countryCode))
			return false;

		if (Iban.length() != countryCharLength.get(countryCode))
			return false;

		String valueToValidate = Iban.substring(4) + Iban.substring(0, 4);

		for (int i = 0; i < valueToValidate.length(); i++) {
			if (charNumbers.containsKey(valueToValidate.charAt(i))) {
				valueToValidate=valueToValidate.replaceAll(
						String.valueOf(countryCode.charAt(i)),
						charNumbers.get(countryCode.charAt(i)).toString());
			}
		}
//		String s2 = valueToValidate.replaceAll(
//				String.valueOf(countryCode.charAt(0)),
//				charNumbers.get(countryCode.charAt(0)).toString());
//		String s3 = s2.replaceAll(String.valueOf(countryCode.charAt(1)),
//				charNumbers.get(countryCode.charAt(1)).toString());

		BigInteger myBigInteger = new BigInteger(valueToValidate);
		BigInteger nintyseven = new BigInteger("97");
		int modResult = Integer.parseInt((myBigInteger.mod(nintyseven))
				.toString());

		if (modResult == 1)
			return true;
		else
			return false;

		// TODO: uppercase - char GB WEST
	}

	public static String IbanGenerator(String BankCode, String AccountNumber,
			int CountryPosition) {
		String CountryCode="";
		
		Object[] keys=countryCharLength.keySet().toArray();
		CountryCode=(String) keys[CountryPosition];
		String Bban = BankCode + AccountNumber;
		String temp = Bban + CountryCode + "00";
		for (int i = 0; i < temp.length(); i++) {
			if (charNumbers.containsKey(temp.charAt(i))) {
				temp = temp.replaceAll(String.valueOf(temp.charAt(i)),
						charNumbers.get(temp.charAt(i)).toString());
			}
		}
		BigInteger myBigInteger = new BigInteger(temp);
		BigInteger nintyseven = new BigInteger("97");
		int modResult = Integer.parseInt((myBigInteger.mod(nintyseven))
				.toString());
		modResult=98-modResult;
		
		String modStr = String.valueOf(modResult);
		
		if (modResult < 10)
		{
			modStr = "0" + modStr;
			
		}
		
		return CountryCode+modStr+Bban;
	}

}
